home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / apply.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  53KB  |  2,111 lines

  1. /*    SCCS Id: @(#)apply.c    3.1    92/12/10          */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "edog.h"
  7.  
  8. #ifdef OVLB
  9.  
  10. static const char NEARDATA tools[] = { TOOL_CLASS, 0 };
  11.  
  12. static boolean NEARDATA did_dig_msg;
  13.  
  14. #ifdef TOURIST
  15. static int FDECL(use_camera, (struct obj *));
  16. #endif
  17. static int FDECL(use_towel, (struct obj *));
  18. static void FDECL(use_stethoscope, (struct obj *));
  19. static void FDECL(use_whistle, (struct obj *));
  20. static void FDECL(use_magic_whistle, (struct obj *));
  21. #ifdef WALKIES
  22. static void FDECL(use_leash, (struct obj *));
  23. #endif
  24. STATIC_DCL int NDECL(dig);
  25. #ifdef OVLB
  26. STATIC_DCL schar FDECL(fillholetyp, (int, int));
  27. #endif
  28. static boolean FDECL(wield_tool, (struct obj *));
  29. static int FDECL(use_pick_axe, (struct obj *));
  30. static int FDECL(use_mirror, (struct obj *));
  31. static void FDECL(use_bell, (struct obj *));
  32. static void FDECL(use_candelabrum, (struct obj *));
  33. static void FDECL(use_candle, (struct obj *));
  34. static void FDECL(use_lamp, (struct obj *));
  35. static void FDECL(use_tinning_kit, (struct obj *));
  36. static void FDECL(use_figurine, (struct obj *));
  37. static void FDECL(use_grease, (struct obj *));
  38. static boolean NDECL(rm_waslit);
  39. static void FDECL(mkcavepos, (XCHAR_P,XCHAR_P,int,BOOLEAN_P,BOOLEAN_P));
  40. static void FDECL(mkcavearea, (BOOLEAN_P));
  41.  
  42. #ifdef TOURIST
  43. static int
  44. use_camera(obj)
  45.     struct obj *obj;
  46. {
  47.     register struct monst *mtmp;
  48.  
  49.     if(Underwater) {
  50.         pline("Using your camera underwater voids the warranty.");
  51.         return(0);
  52.     }
  53.     if(!getdir(NULL)) return(0);
  54.     if(u.uswallow) {
  55.         You("take a picture of %s's %s.", mon_nam(u.ustuck),
  56.             is_animal(u.ustuck->data) ? "stomach" : "interior");
  57.     } else if(obj->cursed && !rn2(2)) goto blindu;
  58.     else if(u.dz) {
  59.         You("take a picture of the %s.",
  60.             (u.dz > 0) ? "floor" : "ceiling");
  61.     } else if(!u.dx && !u.dy) {
  62. blindu:
  63.         if(!Blind) {
  64.             You("are blinded by the flash!");
  65.             make_blinded((long)rnd(25),FALSE);
  66.         }
  67.     } else if(mtmp = bhit(u.dx,u.dy,COLNO,FLASHED_LIGHT,
  68.                         (int(*)())0,(int(*)())0,obj)) {
  69.         if(mtmp->msleep) {
  70.             mtmp->msleep = 0;
  71.             if(cansee(mtmp->mx,mtmp->my))
  72.             pline("The flash awakens %s.", mon_nam(mtmp)); /* a3 */
  73.         } else if (mtmp->data->mlet != S_LIGHT)
  74.             if((mtmp->mcansee && haseyes(mtmp->data))
  75.                || mtmp->mblinded) {
  76.             register int tmp = distu(mtmp->mx,mtmp->my);
  77.             register int tmp2;
  78.  
  79.             if(cansee(mtmp->mx,mtmp->my))
  80.                 pline("%s is blinded by the flash!", Monnam(mtmp));
  81.             if(mtmp->data == &mons[PM_GREMLIN]) {
  82.                 /* Rule #1: Keep them out of the light. */
  83.                 pline("%s cries out in pain!", Monnam(mtmp));
  84.                 if (mtmp->mhp > 1) mtmp->mhp--;
  85.             }
  86.             setmangry(mtmp);
  87.             if(tmp < 9 && !mtmp->isshk && rn2(4)) {
  88.                 mtmp->mflee = 1;
  89.                 if(rn2(4)) mtmp->mfleetim = rnd(100);
  90.             }
  91.             mtmp->mcansee = 0;
  92.             if(tmp < 3) {
  93.                 mtmp->mblinded = 0;
  94.             } else {
  95.                 tmp2 = mtmp->mblinded;
  96.                 tmp2 += rnd(1 + 50/tmp);
  97.                 if(tmp2 > 127) tmp2 = 127;
  98.                 mtmp->mblinded = tmp2;
  99.             }
  100.             }
  101.     }
  102.     return 1;
  103. }
  104. #endif
  105.  
  106. static int
  107. use_towel(obj)
  108.     struct obj *obj;
  109. {
  110.     if(!freehand()) {
  111.         You("have no free %s!", body_part(HAND));
  112.         return 0;
  113.     } else if (obj->owornmask) {
  114.         You("can't use it while you're wearing it!");
  115.         return 0;
  116.     } else if (obj->cursed) {
  117.         long old;
  118.         switch (rn2(3)) {
  119.         case 2:
  120.             old = Glib;
  121.             Glib += rn1(10, 3);
  122.             Your("%s are %s!", makeplural(body_part(HAND)),
  123.             (old ? "filthier than ever" : "now slimy"));
  124.             return 1;
  125.         case 1:
  126.             if (!Blindfolded) {
  127.             old = u.ucreamed;
  128.             u.ucreamed += rn1(10, 3);
  129.             pline("Yecch! Your %s %s gunk on it!", body_part(FACE),
  130.                   (old ? "has more" : "now has"));
  131.             make_blinded(Blinded + (long)u.ucreamed - old, TRUE);
  132.             } else {
  133.             if (ublindf->cursed) {
  134.                 You("pushed your blindfold %s.",
  135.                 rn2(2) ? "cock-eyed" : "crooked");
  136.             } else {
  137.                 You("pushed your blindfold off.");
  138.                 Blindf_off(ublindf);
  139.                 dropx(ublindf);
  140.             }
  141.             }
  142.             return 1;
  143.         case 0:
  144.             break;
  145.         }
  146.     }
  147.  
  148.     if (Glib) {
  149.         Glib = 0;
  150.         You("wipe off your %s.", makeplural(body_part(HAND)));
  151.         return 1;
  152.     } else if(u.ucreamed) {
  153.         Blinded -= u.ucreamed;
  154.         u.ucreamed = 0;
  155.  
  156.         if (!Blinded) {
  157.             pline("You've got the glop off.");
  158.             Blinded = 1;
  159.             make_blinded(0L,TRUE);
  160.         } else {
  161.             Your("%s feels clean now.", body_part(FACE));
  162.         }
  163.         return 1;
  164.     }
  165.  
  166.     Your("%s and %s are already clean.", 
  167.         body_part(FACE), makeplural(body_part(HAND)));
  168.  
  169.     return 0;
  170. }
  171.  
  172. static char hollow_str[] = "hear a hollow sound!  This must be a secret %s!";
  173.  
  174. /* Strictly speaking it makes no sense for usage of a stethoscope to
  175.    not take any time; however, unless it did, the stethoscope would be
  176.    almost useless. */
  177. static void
  178. use_stethoscope(obj)
  179.     register struct obj *obj;
  180. {
  181.     register struct monst *mtmp;
  182.     register struct rm *lev;
  183.     register int rx, ry;
  184.  
  185.     if(!freehand()) {
  186.         You("have no free %s!", body_part(HAND));
  187.         return;
  188.     }
  189.     if (!getdir(NULL)) return;
  190.     if (u.uswallow && (u.dx || u.dy || u.dz)) {
  191.         mstatusline(u.ustuck);
  192.         return;
  193.     } else if (u.dz) {
  194.         if (Underwater)
  195.             You("hear faint splashing.");
  196.         else if (u.dz < 0 || Levitation)
  197.             You("can't reach the %s!", u.dz<0 ? "ceiling" : "floor");
  198.         else if (Is_stronghold(&u.uz))
  199.             You("hear the crackling of hellfire.");
  200.         else
  201.             pline("The floor seems healthy enough.");
  202.         return;
  203.     } else if (obj->cursed && !rn2(2)) {
  204.         You("hear your heart beat.");
  205.         return;
  206.     }
  207.     if (Stunned || (Confusion && !rn2(5))) confdir();
  208.     if (!u.dx && !u.dy) {
  209.         ustatusline();
  210.         return;
  211.     }
  212.     rx = u.ux + u.dx; ry = u.uy + u.dy;
  213.     if (!isok(rx,ry)) {
  214.         You("hear a faint typing noise.");
  215.         return;
  216.     }
  217.     if(mtmp = m_at(rx,ry)) {
  218.         mstatusline(mtmp);
  219.         if (mtmp->mundetected) {
  220.             mtmp->mundetected = 0;
  221.             if (cansee(rx,ry)) newsym(mtmp->my,mtmp->my);
  222.         }
  223.         return;
  224.     }
  225.     lev = &levl[rx][ry];
  226.     switch(lev->typ) {
  227.     case SDOOR:
  228.         You(hollow_str, "door");
  229.         lev->typ = DOOR;
  230.         newsym(rx,ry);
  231.         return;
  232.     case SCORR:
  233.         You(hollow_str, "passage");
  234.         lev->typ = CORR;
  235.         newsym(rx,ry);
  236.         return;
  237.     }
  238.     You("hear nothing special.");
  239. }
  240.  
  241. static char whistle_str[] = "produce a %s whistling sound.";
  242.  
  243. /*ARGSUSED*/
  244. static void
  245. use_whistle(obj)
  246. struct obj *obj;
  247. {
  248.     You(whistle_str, "high");
  249.     wake_nearby();
  250. }
  251.  
  252. static void
  253. use_magic_whistle(obj)
  254. struct obj *obj;
  255. {
  256.     register struct monst *mtmp;
  257.  
  258.     if(obj->cursed && !rn2(2)) {
  259.         You("produce a high-pitched humming noise.");
  260.         wake_nearby();
  261.     } else {
  262.         makeknown(MAGIC_WHISTLE);
  263.         You(whistle_str, Hallucination ? "normal" : "strange");
  264.         for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  265.             if(mtmp->mtame) mnexto(mtmp);
  266.     }
  267. }
  268.  
  269. boolean
  270. um_dist(x,y,n)
  271. register xchar x, y, n;
  272. {
  273.     return(abs(u.ux - x) > n  || abs(u.uy - y) > n);
  274. }
  275.  
  276. #endif /* OVLB */
  277.  
  278. #ifdef WALKIES
  279. #define MAXLEASHED    2
  280.  
  281. #ifdef OVLB
  282.  
  283. int
  284. number_leashed()
  285. {
  286.     register int i = 0;
  287.     register struct obj *obj;
  288.  
  289.     for(obj = invent; obj; obj = obj->nobj)
  290.         if(obj->otyp == LEASH && obj->leashmon != 0) i++;
  291.     return(i);
  292. }
  293.  
  294. void
  295. o_unleash(otmp)     /* otmp is about to be destroyed or stolen */
  296. register struct obj *otmp;
  297. {
  298.     register struct monst *mtmp;
  299.  
  300.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  301.         if(mtmp->m_id == (unsigned)otmp->leashmon)
  302.             mtmp->mleashed = 0;
  303.     otmp->leashmon = 0;
  304. }
  305.  
  306. void
  307. m_unleash(mtmp)     /* mtmp is about to die, or become untame */
  308. register struct monst *mtmp;
  309. {
  310.     register struct obj *otmp;
  311.  
  312.     for(otmp = invent; otmp; otmp = otmp->nobj)
  313.         if(otmp->otyp == LEASH &&
  314.                 otmp->leashmon == (int)mtmp->m_id)
  315.             otmp->leashmon = 0;
  316.     mtmp->mleashed = 0;
  317. }
  318.  
  319. void
  320. unleash_all()        /* player is about to die (for bones) */
  321. {
  322.     register struct obj *otmp;
  323.     register struct monst *mtmp;
  324.  
  325.     for(otmp = invent; otmp; otmp = otmp->nobj)
  326.         if(otmp->otyp == LEASH) otmp->leashmon = 0;
  327.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  328.         if(mtmp->mtame) mtmp->mleashed = 0;
  329. }
  330.  
  331. /* ARGSUSED */
  332. static void
  333. use_leash(obj)
  334. struct obj *obj;
  335. {
  336.     register int x, y;
  337.     register struct monst *mtmp;
  338.     int spotmon;
  339.  
  340.     if(!obj->leashmon && number_leashed() >= MAXLEASHED) {
  341.         You("can't leash additional pets.");
  342.         return;
  343.     }
  344.  
  345.     if(!getdir(NULL)) return;
  346.  
  347.     x = u.ux + u.dx;
  348.     y = u.uy + u.dy;
  349.  
  350.     if((x == u.ux) && (y == u.uy)) {
  351.         pline("Leash yourself?  Very funny...");
  352.         return;
  353.     }
  354.  
  355.     if(!(mtmp = m_at(x, y))) {
  356.         pline("There is no creature here.");
  357.         return;
  358.     }
  359.  
  360.     spotmon = canseemon(mtmp) || sensemon(mtmp);
  361.  
  362.     if(!mtmp->mtame) {
  363.         if(!spotmon)
  364.         pline("There is no creature here.");
  365.         else
  366.         pline("%s is not %s!", Monnam(mtmp), (!obj->leashmon) ?
  367.                 "leashable" : "leashed");
  368.         return;
  369.     }
  370.     if(!obj->leashmon) {
  371.         if(mtmp->mleashed) {
  372.             pline("This %s is already leashed!",
  373.                   spotmon ? l_monnam(mtmp) : "monster");
  374.             return;
  375.         }
  376.         You("slip the leash around %s%s.",
  377.             spotmon ? "your " : "", l_monnam(mtmp));
  378.         mtmp->mleashed = 1;
  379.         obj->leashmon = (int)mtmp->m_id;
  380.         if(mtmp->msleep)  mtmp->msleep = 0;
  381.         return;
  382.     }
  383.     if(obj->leashmon != (int)mtmp->m_id) {
  384.         pline("This leash is not attached to that creature!");
  385.         return;
  386.     } else {
  387.         if(obj->cursed) {
  388.             pline("The leash wouldn't come off!");
  389.             return;
  390.         }
  391.         mtmp->mleashed = 0;
  392.         obj->leashmon = 0;
  393.         You("remove the leash from %s%s.",
  394.             spotmon ? "your " : "", l_monnam(mtmp));
  395.     }
  396.     return;
  397. }
  398.  
  399. #endif /* OVLB */
  400. #ifdef OVL1
  401.  
  402. boolean
  403. next_to_u()
  404. {
  405.     register struct monst *mtmp;
  406.     register struct obj *otmp;
  407.  
  408.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  409.         if(mtmp->mleashed) {
  410.             if (distu(mtmp->mx,mtmp->my) > 2) mnexto(mtmp);
  411.             if (distu(mtmp->mx,mtmp->my) > 2) {
  412.                 for(otmp = invent; otmp; otmp = otmp->nobj)
  413.                 if(otmp->otyp == LEASH &&
  414.                     otmp->leashmon == (int)mtmp->m_id) {
  415.                     if(otmp->cursed) return(FALSE);
  416.                     You("feel %s leash go slack.",
  417.                     (number_leashed() > 1) ? "a" : "the");
  418.                     mtmp->mleashed = 0;
  419.                     otmp->leashmon = 0;
  420.                 }
  421.             }
  422.         }
  423.     return(TRUE);
  424. }
  425.  
  426. #endif /* OVL1 */
  427. #ifdef OVLB
  428. struct obj *
  429. get_mleash(mtmp)     /* assuming mtmp->mleashed has been checked */
  430. register struct monst *mtmp;
  431. {
  432.     register struct obj *otmp;
  433.  
  434.     otmp = invent;
  435.     while(otmp) {
  436.         if(otmp->otyp == LEASH && otmp->leashmon == (int)mtmp->m_id)
  437.             return(otmp);
  438.         otmp = otmp->nobj;
  439.     }
  440.     return((struct obj *)0);
  441. }
  442. #endif /* OVLB */
  443.  
  444. #endif /* WALKIES */
  445. #ifdef OVL0
  446.  
  447. #ifdef WALKIES
  448. void
  449. check_leash(x, y)
  450. register xchar x, y;
  451. {
  452.     register struct obj *otmp;
  453.     register struct monst *mtmp = fmon;
  454.  
  455.     for(otmp = invent; otmp; otmp = otmp->nobj)
  456.         if(otmp->otyp == LEASH && otmp->leashmon != 0) {
  457.         while(mtmp) {
  458.             if((int)mtmp->m_id == otmp->leashmon &&
  459.                 (dist2(u.ux,u.uy,mtmp->mx,mtmp->my) >
  460.                 dist2(x,y,mtmp->mx,mtmp->my))
  461.             ) {
  462.             if(otmp->cursed) {
  463.                 if(um_dist(mtmp->mx, mtmp->my, 5)) {
  464.                 pline("%s chokes to death!",Monnam(mtmp));
  465.                 mondied(mtmp);
  466.                 } else
  467.                 if(um_dist(mtmp->mx, mtmp->my, 3))
  468.                     pline("%s chokes on the leash!",
  469.                         Monnam(mtmp));
  470.             } else {
  471.                 if(um_dist(mtmp->mx, mtmp->my, 5)) {
  472.                 pline("%s's leash snaps loose!",Monnam(mtmp));
  473.                 m_unleash(mtmp);
  474.                 } else {
  475.                 if(um_dist(mtmp->mx, mtmp->my, 3)) {
  476.                     You("pull on the leash.");
  477. # ifdef SOUNDS
  478.                     if (mtmp->data->msound != MS_SILENT)
  479.                     switch(rn2(3)) {
  480.                     case 0:  growl(mtmp);    break;
  481.                     case 1:  yelp(mtmp);    break;
  482.                     default: whimper(mtmp); break;
  483.                     }
  484. # endif
  485.                 }
  486.                 }
  487.             }
  488.             }
  489.             mtmp = mtmp->nmon;
  490.         }
  491.         }
  492. }
  493.  
  494. #endif /* WALKIES */
  495.  
  496. #endif /* OVL0 */
  497. #ifdef OVLB
  498.  
  499. static boolean
  500. rm_waslit() {
  501.     register xchar x, y;
  502.  
  503.     if(levl[u.ux][u.uy].typ == ROOM && levl[u.ux][u.uy].waslit) 
  504.         return(TRUE);
  505.     for(x = u.ux-2; x < u.ux+3; x++)
  506.         for(y = u.uy-1; y < u.uy+2; y++)
  507.         if(isok(x,y) && levl[x][y].waslit) return(TRUE);
  508.     return(FALSE);
  509. }
  510.  
  511. /* Change level topology.  Messes with vision tables and ignores things like
  512.  * boulders in the name of a nice effect.  Vision will get fixed up again
  513.  * immediately after the effect is complete.
  514.  */
  515. static void
  516. mkcavepos(x, y, dist, waslit, rockit)
  517.     xchar x,y;
  518.     int dist;
  519.     boolean waslit, rockit;
  520. {
  521.     register struct rm *lev;
  522.  
  523.     if(!isok(x,y)) return;
  524.     lev = &levl[x][y];
  525.  
  526.     if(rockit) {
  527.         register struct monst *mtmp;
  528.  
  529.         if(IS_ROCK(lev->typ)) return;
  530.     if(t_at(x, y)) return; /* don't cover the portal */
  531.     if(mtmp = m_at(x, y)) /* make sure crucial monsters survive */
  532.         if(!passes_walls(mtmp->data)) rloc(mtmp);
  533.     } else if(lev->typ == ROOM) return;
  534.  
  535.     unblock_point(x,y);    /* make sure vision knows this location is open */
  536.  
  537.     /* fake out saved state */
  538.     lev->seen = FALSE;
  539.     lev->doormask = 0;
  540.     if(dist < 3) lev->lit = (rockit ? FALSE : TRUE);
  541.     if(waslit) lev->waslit = (rockit ? FALSE : TRUE);
  542.     lev->horizontal = FALSE;
  543.     viz_array[y][x] = (dist < 3 ) ?
  544.     (IN_SIGHT|COULD_SEE) : /* short-circuit vision recalc */
  545.     COULD_SEE;
  546.     lev->typ = (rockit ? STONE : ROOM);
  547.     if(dist >= 3)
  548.     impossible("mkcavepos called with dist %d", dist);
  549.     if(Blind)
  550.     feel_location(x, y);
  551.     else newsym(x,y);
  552. }
  553.  
  554. static void
  555. mkcavearea(rockit)
  556. register boolean rockit;
  557. {
  558.     int dist;
  559.     xchar xmin = u.ux, xmax = u.ux;
  560.     xchar ymin = u.uy, ymax = u.uy;
  561.     register xchar i;
  562.     register boolean waslit = rm_waslit();
  563.  
  564.     if(rockit) pline("Crash!  The ceiling collapses around you!");
  565.     else pline("A mysterious force %s cave around you!",
  566.          (levl[u.ux][u.uy].typ == CORR) ? "creates a" : "extends the");
  567.     display_nhwindow(WIN_MESSAGE, TRUE);
  568.  
  569.     for(dist = 1; dist <= 2; dist++) {
  570.     xmin--; xmax++;
  571.  
  572.     /* top and bottom */
  573.     if(dist < 2) { /* the area is wider that it is high */
  574.         ymin--; ymax++;
  575.         for(i = xmin+1; i < xmax; i++) {
  576.         mkcavepos(i, ymin, dist, waslit, rockit);
  577.         mkcavepos(i, ymax, dist, waslit, rockit);
  578.         }
  579.     }
  580.  
  581.     /* left and right */
  582.     for(i = ymin; i <= ymax; i++) {
  583.         mkcavepos(xmin, i, dist, waslit, rockit);
  584.         mkcavepos(xmax, i, dist, waslit, rockit);
  585.     }
  586.  
  587.     flush_screen(1);    /* make sure the new glyphs shows up */
  588.     delay_output();
  589.     }
  590.  
  591.     if(!rockit && levl[u.ux][u.uy].typ == CORR) {
  592.         levl[u.ux][u.uy].typ = ROOM;
  593.     if(waslit) levl[u.ux][u.uy].waslit = TRUE;
  594.     newsym(u.ux, u.uy); /* in case player is invisible */
  595.     }
  596.  
  597.     vision_full_recalc = 1;    /* everything changed */
  598. }
  599.  
  600. STATIC_OVL int
  601. dig()
  602. {
  603.     register struct rm *lev;
  604.     register xchar dpx = dig_pos.x, dpy = dig_pos.y;
  605.  
  606.     lev = &levl[dpx][dpy];
  607.     /* perhaps a nymph stole your pick-axe while you were busy digging */
  608.     /* or perhaps you teleported away */
  609.     if(u.uswallow || !uwep || uwep->otyp != PICK_AXE ||
  610.         !on_level(&dig_level, &u.uz) ||
  611.         ((dig_down && (dpx != u.ux || dpy != u.uy)) ||
  612.          (!dig_down && distu(dpx,dpy) > 2)))
  613.         return(0);
  614.     if (dig_down) {
  615.         if(On_stairs(u.ux, u.uy)) {
  616.         if(u.ux == xdnladder || u.ux == xupladder)
  617.              pline("The ladder resists your effort.");
  618.         else pline("The stairs here are too hard to dig in.");
  619.         return(0);
  620.         }
  621.         if(IS_THRONE(levl[u.ux][u.uy].typ)) {
  622.         pline("The throne here is too hard to break apart.");
  623.         return (0);
  624.         }
  625.         if(IS_ALTAR(levl[u.ux][u.uy].typ)) {
  626.         pline("The altar here is too hard to break apart.");
  627.         return (0);
  628.         }
  629.         if(t_at(dpx, dpy) && !Can_dig_down(&u.uz)) {
  630.         pline("The floor here is too hard to dig in.");
  631.         return(0);
  632.         }
  633.         if(sobj_at(BOULDER, dpx, dpy)) {
  634.         pline("There is not enough room here to dig.");
  635.         return(0);
  636.         }
  637.         if(Is_airlevel(&u.uz)) {
  638.         You("cannot dig in thin air.");
  639.         return(0);
  640.         }
  641.         if(Is_waterlevel(&u.uz)) {
  642.         pline("The water splashes and subsides.");
  643.         return(0);
  644.         }
  645.     } else /* !dig_down */
  646.         if(IS_ROCK(lev->typ) && !may_dig(dpx,dpy)) {
  647.         pline("This wall is too hard to dig into.");
  648.         return(0);
  649.         }
  650.     if(Fumbling && !rn2(3)) {
  651.         switch(rn2(3)) {
  652.         case 0:  if(!welded(uwep)) {
  653.                  You("fumble and drop your %s.", xname(uwep));
  654.                  dropx(uwep);
  655.                  setuwep((struct obj *)0);
  656.              } else {
  657.                  pline("Ouch!  Your %s bounces and hits you!",
  658.                 xname(uwep));
  659.                  set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
  660.              }
  661.              break;
  662.         case 1:  pline("Bang!  You hit with the broad side of %s!",
  663.                    the(xname(uwep)));
  664.              break;
  665.         default: Your("swing misses its mark."); 
  666.              break;
  667.         }
  668.         return(0);
  669.     }
  670.     dig_effort += 10 + abon() + uwep->spe - uwep->oeroded + rn2(5);
  671.     if(dig_down) {
  672.         register struct trap *ttmp;
  673.  
  674.         if(dig_effort > 250) {
  675.             dighole();
  676.             dig_level.dnum = 0;
  677.             dig_level.dlevel = -1;
  678.             return(0);    /* done with digging */
  679.         }
  680.  
  681.         if (dig_effort <= 50)
  682.             return(1);
  683.  
  684.         if ((ttmp = t_at(dpx,dpy)) &&
  685.             ((ttmp->ttyp == PIT) || (ttmp->ttyp == SPIKED_PIT) ||
  686.              (ttmp->ttyp == TRAPDOOR)))
  687.             return(1);
  688.  
  689.         if (IS_ALTAR(lev->typ)) {
  690.             altar_wrath(dpx, dpy);
  691.             angry_priest();
  692.         }
  693.  
  694.         ttmp = maketrap(dpx,dpy,PIT);
  695.         ttmp->tseen = 1;
  696.         if(Invisible) newsym(ttmp->tx,ttmp->ty);
  697.         You("have dug a pit.");
  698.         u.utrap = rn1(4,2);
  699.         u.utraptype = TT_PIT;
  700.         vision_full_recalc = 1;    /* vision limits change */
  701.         dig_level.dnum = 0;
  702.         dig_level.dlevel = -1;
  703.         return(0);
  704.     } 
  705.     if(dig_effort > 100) {
  706.         register const char *digtxt, *dmgtxt = (const char*) 0;
  707.         register struct obj *obj;
  708.         register boolean shopedge = *in_rooms(dpx, dpy, SHOPBASE);
  709.  
  710.         if(obj = sobj_at(STATUE, dpx, dpy)) {
  711.             if (break_statue(obj))
  712.                 digtxt = "The statue shatters.";
  713.             else
  714.                 /* it was a statue trap; break_statue()
  715.                  * printed a message and updated the screen
  716.                  */
  717.                 digtxt = NULL;
  718.         } else if(obj = sobj_at(BOULDER, dpx, dpy)) {
  719.             fracture_rock(obj);
  720.             digtxt = "The boulder falls apart.";
  721.         } else if(!lev->typ || lev->typ == SCORR) {
  722.                 if(Is_earthlevel(&u.uz)) {
  723.                 if(uwep->blessed && !rn2(3)) {
  724.                     mkcavearea(FALSE);
  725.                 goto cleanup;
  726.                 } else if((uwep->cursed && !rn2(4)) || 
  727.                           (!uwep->blessed && !rn2(6))) {
  728.                     mkcavearea(TRUE);
  729.                     goto cleanup;
  730.                 }
  731.             }
  732.             lev->typ = CORR;
  733.             digtxt = "You succeeded in cutting away some rock.";
  734.         } else if(IS_WALL(lev->typ)) {
  735.             if(shopedge) {
  736.                     add_damage(dpx, dpy, 10L * ACURRSTR);
  737.                 dmgtxt = "dig into";
  738.             }
  739.                 if (level.flags.is_maze_lev) {
  740.                 lev->typ = ROOM;
  741.                 } else if (level.flags.is_cavernous_lev) {
  742.                 lev->typ = CORR;
  743.             } else {
  744.                 lev->typ = DOOR;
  745.                 lev->doormask = D_NODOOR;
  746.             }
  747.             digtxt = "You just made an opening in the wall.";
  748.         } else if(lev->typ == SDOOR) {
  749.             lev->typ = DOOR;
  750.             digtxt = "You just broke through a secret door.";
  751.             if(!(lev->doormask & D_TRAPPED))
  752.                 lev->doormask = D_BROKEN;
  753.         } else if(closed_door(dpx, dpy)) {
  754.             digtxt = "You just broke a hole through the door.";
  755.             if(shopedge) {
  756.                     add_damage(dpx, dpy, 400L);
  757.                 dmgtxt = "break";
  758.             }
  759.             if(!(lev->doormask & D_TRAPPED))
  760.                 lev->doormask = D_BROKEN;
  761.         } else return(0); /* statue or boulder got taken */
  762.  
  763.         unblock_point(dpx,dpy);    /* vision:  can see through */
  764.         if(Blind)
  765.             feel_location(dpx, dpy);
  766.         else
  767.             newsym(dpx, dpy);
  768.         if(digtxt) pline(digtxt);    /* after newsym */
  769.         if(dmgtxt)
  770.             pay_for_damage(dmgtxt);
  771.  
  772.         if(Is_earthlevel(&u.uz) && !rn2(3)) {
  773.             register struct monst *mtmp;
  774.  
  775.             switch(rn2(2)) {
  776.               case 0: 
  777.                 mtmp = makemon(&mons[PM_EARTH_ELEMENTAL], dpx, dpy);
  778.             break;
  779.               default: 
  780.             mtmp = makemon(&mons[PM_XORN], dpx, dpy); 
  781.             break;
  782.             }
  783.             if(mtmp) pline("The debris of your dig comes alive!");
  784.         }
  785.         if(IS_DOOR(lev->typ) && (lev->doormask & D_TRAPPED)) {
  786.             b_trapped("door");
  787.             lev->doormask = D_NODOOR;
  788.             newsym(dpx, dpy);
  789.         }
  790. cleanup:
  791.         dig_level.dnum = 0;
  792.         dig_level.dlevel = -1;
  793.         return(0);
  794.     } else {
  795.         if(IS_WALL(lev->typ) || closed_door(dpx, dpy)) {
  796.             if(*in_rooms(dpx, dpy, SHOPBASE)) {
  797.             pline("This %s seems too hard to dig into.",
  798.                   IS_DOOR(lev->typ) ? "door" : "wall");
  799.             return(0);
  800.             }
  801.         } else if (!IS_ROCK(lev->typ) && !sobj_at(STATUE, dpx, dpy)
  802.                 && !sobj_at(BOULDER, dpx, dpy))
  803.             return(0); /* statue or boulder got taken */
  804.         if(!did_dig_msg) {
  805.             You("hit the %s with all your might.",
  806.             sobj_at(STATUE, dpx, dpy) ? "statue" :
  807.             sobj_at(BOULDER, dpx, dpy) ? "boulder" :
  808.             IS_DOOR(lev->typ) ? "door" : "rock");
  809.             did_dig_msg = TRUE;
  810.         }
  811.     }
  812.     return(1);
  813. }
  814.  
  815. /* When will hole be finished? Very rough indication used by shopkeeper. */
  816. int
  817. holetime() {
  818.     if(occupation != dig || !*u.ushops) return(-1);
  819.     return((250 - dig_effort)/20);
  820. }
  821.  
  822. /* Return typ of liquid to fill a hole with, or ROOM, if no liquid nearby */
  823. STATIC_OVL
  824. schar
  825. fillholetyp(x,y)
  826. int x, y;
  827. {
  828.     register int x1, y1;
  829.  
  830.     for(x1 = max(1,x-1); x1<=min(x+1,COLNO-1); x1++)
  831.     for(y1 = max(0,y-1); y1<=min(y+1,ROWNO-1); y1++)
  832.         if(levl[x1][y1].typ == MOAT || levl[x1][y1].typ == LAVAPOOL)
  833.         return levl[x1][y1].typ;
  834.  
  835.     return ROOM;
  836. }
  837.  
  838. void
  839. dighole()
  840. {
  841.     register struct trap *ttmp = t_at(u.ux, u.uy);
  842.     struct rm *lev = &levl[u.ux][u.uy];
  843.     struct obj *boulder_here;
  844.     boolean nohole = !Can_dig_down(&u.uz);
  845.  
  846.     if(ttmp && nohole) {
  847.         pline("The floor here seems too hard to dig in.");
  848.     } else {
  849.         d_level    newlevel;
  850.  
  851.         if (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) {
  852.             pline(
  853.                "The %s sloshes furiously for a moment, then subsides.",
  854.               is_lava(u.ux, u.uy) ? "lava" : "water");
  855.             return;
  856.         }
  857.         if (lev->typ == DRAWBRIDGE_DOWN) {
  858.             destroy_drawbridge(u.ux,u.uy);
  859.             return;
  860.         } else if (boulder_here = sobj_at(BOULDER, u.ux, u.uy)) {
  861.             if (ttmp && ((ttmp->ttyp == PIT) || 
  862.                       (ttmp->ttyp == SPIKED_PIT))) {
  863.                 pline("The boulder settles into the pit.");
  864.                 ttmp->ttyp = PIT;      /* crush spikes */
  865.             } else {
  866.                 /*
  867.                  * digging makes a hole, but the boulder
  868.                  * immediately fills it.  Final outcome:
  869.                  * no hole, no boulder.
  870.                  */
  871.                 pline("KADOOM! The boulder falls in!");
  872.  
  873.                 /* destroy traps that emanate from the floor */
  874.                 /* some of these are arbitrary -dlc */
  875.                 if (ttmp && ((ttmp->ttyp == SQKY_BOARD) ||
  876.                          (ttmp->ttyp == BEAR_TRAP) ||
  877.                          (ttmp->ttyp == LANDMINE) ||
  878.                          (ttmp->ttyp == FIRE_TRAP) ||
  879.                          (ttmp->ttyp == TRAPDOOR) ||
  880.                          (ttmp->ttyp == TELEP_TRAP) ||
  881.                          (ttmp->ttyp == LEVEL_TELEP) ||
  882.                          (ttmp->ttyp == WEB) ||
  883.                          (ttmp->ttyp == MAGIC_TRAP) ||
  884.                          (ttmp->ttyp == ANTI_MAGIC))) {
  885.                     deltrap(ttmp);
  886.                     u.utrap = 0;
  887.                     u.utraptype = 0;
  888.                 }
  889.             }
  890.             delobj(boulder_here);
  891.             return;
  892.         }
  893.         if (lev->typ == DRAWBRIDGE_UP) {
  894.             /* must be floor or ice, other cases handled above */
  895.             /* dig "pit" and let fluid flow in (if possible) */
  896.             schar typ = fillholetyp(u.ux,u.uy);
  897.  
  898.             if(typ == ROOM) {
  899.                 if(lev->drawbridgemask & DB_ICE)
  900.                 typ = MOAT;
  901.                 else {
  902.                 /*
  903.                  * We can't dig a pit here since that will
  904.                  * destroy the drawbridge.  The following is
  905.                  * a cop-out. --dlc
  906.                  */
  907.                 pline("The floor here seems too hard to dig in.");
  908.                 return;
  909.                 }
  910.             }
  911.  
  912.                 lev->drawbridgemask &= DB_DIR;
  913.             if(typ == LAVAPOOL) lev->drawbridgemask |= DB_LAVA;
  914.             newsym(u.ux,u.uy);
  915.  
  916.             pline("As you dig a pit, it fills with %s!",
  917.                   typ == LAVAPOOL ? "lava" : "water");
  918.             if(!Levitation
  919. #ifdef POLYSELF
  920.                && !is_flyer(uasmon)
  921. #endif
  922.                             ) {
  923.                 if (typ == LAVAPOOL)
  924.                 (void) lava_effects();
  925.                 else if(!Wwalking)
  926.                 (void) drown();
  927.             }
  928.             return;
  929.         } else if (lev->typ == ICE) {
  930.             /* assume we can remove most of the ice by drilling
  931.              * without melting it or allowing neighboring water
  932.              * to flow in.
  933.              */
  934.             lev->typ = ROOM;
  935.         } else if (IS_FOUNTAIN(lev->typ)) {
  936.             dogushforth(FALSE);
  937.             dryup(u.ux,u.uy);
  938.             return;
  939. #ifdef SINKS
  940.         } else if (IS_SINK(lev->typ)) {
  941.             breaksink(u.ux, u.uy);
  942.             return;
  943. #endif
  944.         /* the following two are here for the wand of digging */
  945.         } else if(IS_THRONE(levl[u.ux][u.uy].typ)) {
  946.             pline("The throne here is too hard to break apart.");
  947.             return;
  948.         } else if(IS_ALTAR(levl[u.ux][u.uy].typ)) {
  949.             pline("The altar here is too hard to break apart.");
  950.             return;
  951.         } else if(ttmp) {
  952.             ttmp->ttyp = TRAPDOOR;
  953.         } else if(nohole) {
  954.             /* can't make a trapdoor, so make a pit */
  955.             ttmp = maketrap(u.ux, u.uy, PIT);
  956.         } else
  957.             ttmp = maketrap(u.ux, u.uy, TRAPDOOR);
  958.         ttmp->tseen = 1;
  959.         if(Invisible) newsym(ttmp->tx,ttmp->ty);
  960.         if(ttmp->ttyp == PIT) {
  961.             You("have dug a pit.");
  962.             if(!Levitation) {
  963.             u.utrap = rn1(4,2);
  964.             u.utraptype = TT_PIT;
  965.             vision_full_recalc = 1;    /* vision limits change */
  966.             } else
  967.             u.utrap = 0;
  968.             return;
  969.         } 
  970.         pline("You've made a hole in the floor.");
  971.  
  972.         /* floor objects get a chance of falling down.
  973.          * the case where the hero does NOT fall down
  974.          * is treated here.  the case where the hero
  975.          * does fall down is treated in goto_level().
  976.          */
  977.         if(OBJ_AT(u.ux, u.uy) && (u.ustuck || Levitation 
  978. #ifdef WALKIES
  979.                                  || !next_to_u()
  980. #endif
  981.                       ))
  982.             impact_drop((struct obj *)0, u.ux, u.uy, 0);
  983.  
  984.         if (*u.ushops)
  985.             add_damage(u.ux, u.uy, 0L);
  986.         if(!u.ustuck && !Levitation) {            /* KAA */
  987.             if(*u.ushops)
  988.                 shopdig(1);
  989. #ifdef WALKIES
  990.             if(!next_to_u())
  991.                 You("are jerked back by your pet!");
  992.             else
  993. #endif
  994.             {
  995.                 You("fall through...");
  996.  
  997.                 /* the checks above must ensure that   */
  998.                 /* the destination level exists and is */
  999.                 /* in the present dungeon.           */
  1000.  
  1001.                 newlevel.dnum = u.uz.dnum;
  1002.                 newlevel.dlevel = u.uz.dlevel + 1;
  1003.                 goto_level(&newlevel, FALSE, TRUE, FALSE);
  1004.             }
  1005.         }
  1006.     }
  1007. }
  1008.  
  1009. static boolean
  1010. wield_tool(obj)
  1011. struct obj *obj;
  1012. {
  1013.     if(welded(uwep)) {
  1014.         /* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */
  1015.         if(flags.verbose) {
  1016.             pline("Since your weapon is welded to your %s,",
  1017.                 bimanual(uwep) ?
  1018.                 (const char *)makeplural(body_part(HAND))
  1019.                 : body_part(HAND));
  1020.             pline("you cannot wield that %s.", xname(obj));
  1021.         }
  1022.         return(FALSE);
  1023.     }
  1024. # ifdef POLYSELF
  1025.     if(cantwield(uasmon)) {
  1026.         You("can't hold it strongly enough.");
  1027.         return(FALSE);
  1028.     }
  1029. # endif
  1030.     unweapon = TRUE;
  1031.     You("now wield %s.", doname(obj));
  1032.     setuwep(obj);
  1033.     if (uwep != obj) return(FALSE); /* rewielded old object after dying */
  1034.     return(TRUE);
  1035. }
  1036.  
  1037. static int
  1038. use_pick_axe(obj)
  1039. struct obj *obj;
  1040. {
  1041.     char dirsyms[12];
  1042.     char qbuf[QBUFSZ];
  1043.     register char *dsp = dirsyms;
  1044.     register const char *sdp = flags.num_pad ? ndir : sdir;
  1045.     register struct rm *lev;
  1046.     register int rx, ry, res = 0;
  1047.     register boolean isclosedoor;
  1048.  
  1049.     if(obj != uwep)
  1050.         if (!wield_tool(obj)) return(0);
  1051.         else res = 1;
  1052.  
  1053.     while(*sdp) {
  1054.         (void) movecmd(*sdp);    /* sets u.dx and u.dy and u.dz */
  1055.         rx = u.ux + u.dx;
  1056.         ry = u.uy + u.dy;
  1057.         if(u.dz > 0 || (u.dz == 0 && isok(rx, ry) &&
  1058.             (IS_ROCK(levl[rx][ry].typ)
  1059.             || sobj_at(STATUE, rx, ry)
  1060.             || sobj_at(BOULDER, rx, ry))))
  1061.             *dsp++ = *sdp;
  1062.         sdp++;
  1063.     }
  1064.     *dsp = 0;
  1065.     Sprintf(qbuf, "In what direction do you want to dig? [%s]", dirsyms);
  1066.     if(!getdir(qbuf))
  1067.         return(res);
  1068.     if(u.uswallow && attack(u.ustuck)) /* return(1) */;
  1069.     else if(Underwater) {
  1070.         pline("Turbulence torpedoes your digging attempts.");
  1071.     } else if(u.dz < 0) {
  1072.         if(Levitation)
  1073.             You("don't have enough leverage.");
  1074.         else
  1075.             You("cannot reach the ceiling.");
  1076.     } else if(!u.dx && !u.dy && !u.dz) {
  1077.         char buf[BUFSZ];
  1078.         int dam;
  1079.  
  1080.         dam = rnd(2) + dbon() + obj->spe;
  1081.         if (dam <= 0) dam = 1;
  1082.         You("hit yourself with your own pick-axe.");
  1083.         /* self_pronoun() won't work twice in a sentence */
  1084.         Strcpy(buf, self_pronoun("killed %sself with %%s own pick-axe",
  1085.             "him"));
  1086.         losehp(dam, self_pronoun(buf, "his"), NO_KILLER_PREFIX);
  1087.         flags.botl=1;
  1088.         return(1);
  1089.     } else if(u.dz == 0) {
  1090.         if(Stunned || (Confusion && !rn2(5))) confdir();
  1091.         rx = u.ux + u.dx;
  1092.         ry = u.uy + u.dy;
  1093.         if(!isok(rx, ry)) {
  1094.             pline("Clash!");
  1095.             return(1);
  1096.         }
  1097.         lev = &levl[rx][ry];
  1098.         if(MON_AT(rx, ry) && attack(m_at(rx, ry)))
  1099.             return(1);
  1100.         isclosedoor = closed_door(rx, ry);
  1101.         if(!IS_ROCK(lev->typ)
  1102.              && !isclosedoor
  1103.              && !sobj_at(STATUE, rx, ry)
  1104.              && !sobj_at(BOULDER, rx, ry)) {
  1105.             /* ACCESSIBLE or POOL */
  1106.             You("swing your %s through thin air.",
  1107.                 aobjnam(obj, NULL));
  1108.         } else {
  1109.             if(dig_pos.x != rx || dig_pos.y != ry
  1110.                 || !on_level(&dig_level, &u.uz) || dig_down) {
  1111.                 dig_down = FALSE;
  1112.                 dig_pos.x = rx;
  1113.                 dig_pos.y = ry;
  1114.                 assign_level(&dig_level, &u.uz);
  1115.                 dig_effort = 0;
  1116.                     You("start %s.",
  1117.                    sobj_at(STATUE, rx, ry) ?
  1118.                         "chipping the statue" :
  1119.                    sobj_at(BOULDER, rx, ry) ?
  1120.                         "hitting the boulder" :
  1121.                    isclosedoor ? "chopping at the door" :
  1122.                         "digging");
  1123.             } else
  1124.                 You("continue %s.",
  1125.                    sobj_at(STATUE, rx, ry) ?
  1126.                         "chipping the statue" :
  1127.                    sobj_at(BOULDER, rx, ry) ?
  1128.                         "hitting the boulder" :
  1129.                    isclosedoor ? "chopping at the door" :
  1130.                         "digging");
  1131.             did_dig_msg = FALSE;
  1132.             set_occupation(dig, "digging", 0);
  1133.         }
  1134.     } else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) {
  1135.         /* it must be air -- water checked above */
  1136.         You("swing your %s through thin air.", aobjnam(obj, NULL));
  1137.     } else if(Levitation) {
  1138.         You("cannot reach the floor.");
  1139.     } else if (is_pool(u.ux, u.uy)) {
  1140.         /* Monsters which swim also happen not to be able to dig */
  1141.         You("cannot stay underwater long enough.");
  1142.     } else {
  1143.         if(dig_pos.x != u.ux || dig_pos.y != u.uy
  1144.             || !on_level(&dig_level, &u.uz) || !dig_down) {
  1145.             dig_down = TRUE;
  1146.             dig_pos.x = u.ux;
  1147.             dig_pos.y = u.uy;
  1148.             assign_level(&dig_level, &u.uz);
  1149.             dig_effort = 0;
  1150.             You("start digging in the floor.");
  1151.             if(*u.ushops)
  1152.                 shopdig(0);
  1153.         } else
  1154.             You("continue digging in the floor.");
  1155.         did_dig_msg = FALSE;
  1156.         set_occupation(dig, "digging", 0);
  1157.     }
  1158.     return(1);
  1159. }
  1160.  
  1161. #define WEAK    3    /* from eat.c */
  1162.  
  1163. static char look_str[] = "look %s.";
  1164.  
  1165. static int
  1166. use_mirror(obj)
  1167. struct obj *obj;
  1168. {
  1169.     register struct monst *mtmp;
  1170.     register char mlet;
  1171.     boolean vis;
  1172.  
  1173.     if(!getdir(NULL)) return 0;
  1174.     if(obj->cursed && !rn2(2)) {
  1175.         if (!Blind)
  1176.             pline("The mirror fogs up and doesn't reflect!");
  1177.         return 1;
  1178.     }
  1179.     if(!u.dx && !u.dy && !u.dz) {
  1180.         if(!Blind && !Invisible) {
  1181. #ifdef POLYSELF
  1182.             if(u.umonnum == PM_FLOATING_EYE) {
  1183.             pline(Hallucination ?
  1184.                   "Yow!  The mirror stared back at you!" :
  1185.                   "Yikes!  You've frozen yourself!");
  1186.             nomul(-rnd((MAXULEV+6) - (int)u.ulevel));
  1187.             } else if (u.usym == S_VAMPIRE)
  1188.             You("don't seem to reflect anything.");
  1189.             else if(u.umonnum == PM_UMBER_HULK) {
  1190.             pline("Huh?  That doesn't look like you!");
  1191.             make_confused(HConfusion + d(3,4),FALSE);
  1192.             } else
  1193. #endif
  1194.                if (Hallucination) You(look_str, hcolor());
  1195.             else if (Sick)
  1196.             You(look_str, "peaked");
  1197.             else if (u.uhs >= WEAK)
  1198.             You(look_str, "undernourished");
  1199.             else You("look as %s as ever.",
  1200.                 ACURR(A_CHA) > 14 ?
  1201.                 (poly_gender()==1 ? "beautiful" : "handsome") :
  1202.                 "ugly");
  1203.         } else {
  1204.             You("can't see your %s %s.",
  1205.                 ACURR(A_CHA) > 14 ?
  1206.                 (poly_gender()==1 ? "beautiful" : "handsome") :
  1207.                 "ugly",
  1208.                 body_part(FACE));
  1209.         }
  1210.         return 1;
  1211.     }
  1212.     if(u.uswallow) {
  1213.         if (!Blind) You("reflect %s's %s.", mon_nam(u.ustuck),
  1214.             is_animal(u.ustuck->data)? "stomach" : "interior");
  1215.         return 1;
  1216.     }
  1217.     if(Underwater) {
  1218.         You("offer the fish a chance to do some makeup.");
  1219.         return 1;
  1220.     }
  1221.     if(u.dz) {
  1222.         if (!Blind)
  1223.             You("reflect the %s.", (u.dz > 0) ? "floor" : "ceiling");
  1224.         return 1;
  1225.     }
  1226.     if(!(mtmp = bhit(u.dx,u.dy,COLNO,INVIS_BEAM,
  1227.                     (int(*)())0,(int(*)())0,obj)) ||
  1228.        !haseyes(mtmp->data))
  1229.         return 1;
  1230.  
  1231.     vis = canseemon(mtmp);
  1232.     mlet = mtmp->data->mlet;
  1233.     if(mtmp->msleep) {
  1234.         if (vis)
  1235.             pline ("%s is tired and doesn't look at your mirror.",
  1236.                 Monnam(mtmp));
  1237.     } else if (!mtmp->mcansee) {
  1238.         if (vis)
  1239.         pline("%s can't see anything at the moment.", Monnam(mtmp));
  1240.     /* some monsters do special things */
  1241.     } else if (mlet == S_VAMPIRE || mlet == S_GHOST) {
  1242.         if (vis)
  1243.         pline ("%s doesn't seem to reflect anything.", Monnam(mtmp));
  1244.     } else if(!mtmp->mcan && mtmp->data == &mons[PM_MEDUSA]) {
  1245.         if (vis)
  1246.             pline("%s is turned to stone!", Monnam(mtmp));
  1247.         stoned = TRUE;
  1248.         killed(mtmp);
  1249.     } else if(!mtmp->mcan && !mtmp->minvis &&
  1250.                     mtmp->data == &mons[PM_FLOATING_EYE]) {
  1251.         int tmp = d((int)mtmp->m_lev, (int)mtmp->data->mattk[0].damd);
  1252.         if (!rn2(4)) tmp = 120;
  1253.     /* Note: floating eyes cannot use their abilities while invisible,
  1254.      * but Medusa and umber hulks can.
  1255.      */
  1256.         if (vis)
  1257.             pline("%s is frozen by its reflection.",Monnam(mtmp));
  1258.         else You("hear something stop moving.");
  1259.         mtmp->mcanmove = 0;
  1260.         if ( (int) mtmp->mfrozen + tmp > 127)
  1261.             mtmp->mfrozen = 127;
  1262.         else mtmp->mfrozen += tmp;
  1263.     } else if(!mtmp->mcan && mtmp->data == &mons[PM_UMBER_HULK]) {
  1264.         if (vis)
  1265.             pline ("%s has confused itself!", Monnam(mtmp));
  1266.             mtmp->mconf = 1;
  1267.     } else if(!mtmp->mcan && !mtmp->minvis && (mlet == S_NYMPH
  1268.                          || mtmp->data==&mons[PM_SUCCUBUS])) {
  1269.         if (vis) {
  1270.                 pline ("%s looks beautiful in your mirror.",Monnam(mtmp));
  1271.                 pline ("She decides to take it!");
  1272.         } else pline ("It steals your mirror!");
  1273.         setnotworn(obj); /* in case mirror was wielded */
  1274.             freeinv(obj);
  1275.             mpickobj(mtmp,obj);
  1276.             rloc(mtmp);
  1277.     } else if (mlet != S_UNICORN && !humanoid(mtmp->data) &&
  1278.             (!mtmp->minvis || perceives(mtmp->data)) && rn2(5)) {
  1279.         if (vis)
  1280.             pline ("%s is frightened by its reflection.",
  1281.                 Monnam(mtmp));
  1282.         mtmp->mflee = 1;
  1283.         mtmp->mfleetim += d(2,4);
  1284.     } else if (!Blind) {
  1285.         if (mtmp->minvis && !See_invisible)
  1286.             ;
  1287.         else if ((mtmp->minvis && !perceives(mtmp->data))
  1288.              || !haseyes(mtmp->data))
  1289.             pline("%s doesn't seem to be aware of its reflection.",
  1290.             Monnam(mtmp));
  1291.         else
  1292.             pline("%s doesn't seem to mind %s reflection.",
  1293.             Monnam(mtmp),
  1294.             humanoid(mtmp->data) ? (mtmp->female ? "her" : "his")
  1295.                         : "its");
  1296.     }
  1297.     return 1;
  1298. }
  1299.  
  1300. static void
  1301. use_bell(obj)
  1302. register struct obj *obj;
  1303. {
  1304.     You("ring %s.", the(xname(obj)));
  1305.  
  1306.     if(Underwater) {
  1307.         pline("But it sounds kind of muffled.");
  1308.         return;
  1309.     }
  1310.         if(obj->otyp == BELL) {
  1311.         if(u.uswallow) {
  1312.             pline(nothing_happens);
  1313.         return;
  1314.         }
  1315.         if(obj->cursed && !rn2(3)) {
  1316.             register struct monst *mtmp;
  1317.  
  1318.         if(mtmp = makemon(&mons[PM_WOOD_NYMPH], u.ux, u.uy))
  1319.            You("summon %s!", a_monnam(mtmp));
  1320.         }
  1321.         wake_nearby();
  1322.         return;
  1323.     }
  1324.  
  1325.     /* bell of opening */
  1326.     if(u.uswallow && !obj->blessed) {
  1327.         pline(nothing_happens);
  1328.         return;
  1329.     }
  1330.         if(obj->cursed) {
  1331.         coord mm;
  1332.         mm.x = u.ux;
  1333.         mm.y = u.uy;
  1334.         mkundead(&mm);
  1335. cursed_bell:
  1336.         wake_nearby();
  1337.         if(obj->spe > 0) obj->spe--;
  1338.         return;
  1339.     }
  1340.     if(invocation_pos(u.ux, u.uy) && 
  1341.                  !On_stairs(u.ux, u.uy) && !u.uswallow) {
  1342.         pline("%s emits an unnerving high-pitched sound...",
  1343.                                                   The(xname(obj)));
  1344.         obj->age = moves;
  1345.         if(obj->spe > 0) obj->spe--;
  1346.         wake_nearby();
  1347.         obj->known = 1;
  1348.         return;
  1349.     }
  1350.     if(obj->blessed) {
  1351.         if(obj->spe > 0) {
  1352.             register int cnt = openit();
  1353.         if(cnt == -1) return; /* was swallowed */
  1354.         switch(cnt) {
  1355.           case 0:  pline(nothing_happens); break;
  1356.           case 1:  pline("Something opens..."); break;
  1357.               default: pline("Things open around you..."); break;
  1358.             }
  1359.         if(cnt > 0) obj->known = 1;
  1360.         obj->spe--;
  1361.         } else pline(nothing_happens);
  1362.     } else {  /* uncursed */
  1363.         if(obj->spe > 0) {
  1364.             register int cnt = findit();
  1365.         if(cnt == 0) pline(nothing_happens);
  1366.         else obj->known = 1;
  1367.             obj->spe--;
  1368.         } else {
  1369.             if(!rn2(3)) goto cursed_bell;
  1370.         else pline(nothing_happens);
  1371.         }
  1372.         }
  1373. }
  1374.  
  1375. static void
  1376. use_candelabrum(obj)
  1377. register struct obj *obj;
  1378. {
  1379.     if(Underwater) {
  1380.         You("can't make fire under water.");
  1381.         return;
  1382.     }
  1383.     if(obj->lamplit) {
  1384.         You("snuff the candle%s out.", obj->spe > 1 ? "s" : "");
  1385.         obj->lamplit = 0;
  1386.         check_lamps();
  1387.         return;
  1388.     }
  1389.     if(obj->spe <= 0) {
  1390.         pline("This %s has no candles.", xname(obj));
  1391.         return;
  1392.     }
  1393.     if(u.uswallow || obj->cursed) {
  1394.         pline("The candle%s flicker%s on for a moment, then die%s.", 
  1395.             obj->spe > 1 ? "s" : "",
  1396.             obj->spe > 1 ? "" : "s",
  1397.             obj->spe > 1 ? "" : "s");
  1398.             return;
  1399.     } 
  1400.         if(obj->spe < 7) {
  1401.             pline("There %s only %d candle%s in %s.",
  1402.                obj->spe == 1 ? "is" : "are", 
  1403.                obj->spe,
  1404.                obj->spe > 1 ? "s" : "",
  1405.                the(xname(obj)));
  1406.         pline("%s lit.  %s emits a dim light.",
  1407.                obj->spe == 1 ? "It is" : "They are", The(xname(obj)));
  1408.     } else {
  1409.         pline("%s's candles burn%s", The(xname(obj)),
  1410.             (Blind ? "." : " brightly!"));
  1411.     }
  1412.     if (!invocation_pos(u.ux, u.uy)) {
  1413.         pline("The candle%s being rapidly consumed!",
  1414.             (obj->spe > 1 ? "s are" : " is"));
  1415.         obj->age /= 2;
  1416.     } else {
  1417.             if(obj->spe == 7)
  1418.                 pline("%s glows with a strange light!", The(xname(obj)));
  1419.         obj->known = 1;
  1420.     }
  1421.     obj->lamplit = 1;
  1422.     check_lamps();
  1423. }
  1424.  
  1425. static void
  1426. use_candle(obj)
  1427. register struct obj *obj;
  1428. {
  1429.  
  1430.     register struct obj *otmp;
  1431.     char qbuf[QBUFSZ];
  1432.  
  1433.     if(obj->lamplit) {
  1434.             use_lamp(obj);
  1435.         return;
  1436.     }
  1437.  
  1438.     if(u.uswallow) {
  1439.             You("don't have enough elbow-room to maneuver.");
  1440.         return;
  1441.     }
  1442.     if(Underwater) {
  1443.         pline("Sorry, fire and water don't mix.");
  1444.         return;
  1445.     }
  1446.  
  1447.     for(otmp = invent; otmp; otmp = otmp->nobj) {
  1448.         if(otmp->otyp == CANDELABRUM_OF_INVOCATION && otmp->spe < 7)
  1449.             break;
  1450.     }
  1451.     if(!otmp || otmp->spe == 7) {
  1452.         use_lamp(obj);
  1453.         return;
  1454.     }
  1455.  
  1456.     Sprintf(qbuf, "Attach %s", the(xname(obj)));
  1457.     Sprintf(eos(qbuf), " to %s?", the(xname(otmp)));
  1458.     if(yn(qbuf) == 'n') {
  1459.         You("try to light %s...", the(xname(obj)));
  1460.         use_lamp(obj);
  1461.         return;
  1462.     } else {
  1463.         register long needed = 7L - (long)otmp->spe;
  1464.  
  1465.         You("attach %ld%s candle%s to %s.", 
  1466.             obj->quan >= needed ? needed : obj->quan,
  1467.             !otmp->spe ? "" : " more",
  1468.             (needed > 1L && obj->quan > 1L) ? "s" : "",
  1469.             the(xname(otmp)));
  1470.         if(otmp->lamplit) 
  1471.             pline("The new candle%s magically ignite%s!",
  1472.                 (needed > 1L && obj->quan > 1L) ? "s" : "",
  1473.                 (needed > 1L && obj->quan > 1L) ? "" : "s");
  1474.         if(obj->unpaid) 
  1475.             You("use %s, you bought %s!",
  1476.                 (needed > 1L && obj->quan > 1L) ? "them" : "it",
  1477.                 (needed > 1L && obj->quan > 1L) ? "them" : "it");
  1478.         if(!otmp->spe || otmp->age > obj->age)
  1479.             otmp->age = obj->age;
  1480.         if(obj->quan > needed) {
  1481.             if(obj->unpaid) {
  1482.             /* this is a hack, until we re-write the billing */
  1483.             /* code to accommodate such cases directly. IM*/
  1484.             register long delta = obj->quan - needed;
  1485.  
  1486.             subfrombill(obj, shop_keeper(*u.ushops));
  1487.             obj->quan = needed;
  1488.             addtobill(obj, TRUE, FALSE, TRUE);
  1489.             bill_dummy_object(obj);
  1490.             obj->quan = delta;
  1491.             addtobill(obj, TRUE, FALSE, TRUE);
  1492.              } else {
  1493.             obj->quan -= needed;
  1494.              }
  1495.              otmp->spe += (int)needed;
  1496.         } else {
  1497.             otmp->spe += (int)obj->quan;
  1498.             freeinv(obj);
  1499.             obfree(obj, (struct obj *)0);
  1500.         }
  1501.         if(needed < 7L && otmp->spe == 7)
  1502.             pline("%s has now seven%s candles attached.",
  1503.             The(xname(otmp)), otmp->lamplit ? " lit" : "");
  1504.     }
  1505. }
  1506.  
  1507. boolean
  1508. snuff_candle(otmp)  /* call in drop, throw, and put in box, etc. */
  1509. register struct obj *otmp;
  1510. {
  1511.     register boolean candle = Is_candle(otmp);
  1512.  
  1513.     if ((candle || otmp->otyp == CANDELABRUM_OF_INVOCATION) &&
  1514.         otmp->lamplit) {
  1515.         register boolean many = candle ? otmp->quan > 1L : otmp->spe > 1;
  1516.         pline("The %scandle%s flame%s extinguished.",
  1517.           (candle ? "" : "candelabrum's "),
  1518.           (many ? "s'" : "'s"), (many ? "s are" : " is"));
  1519.        otmp->lamplit = 0;
  1520.        check_lamps();
  1521.        return(TRUE);
  1522.     }
  1523.     return(FALSE);
  1524. }
  1525.  
  1526. boolean
  1527. snuff_lit(obj)
  1528. struct obj *obj;
  1529. {
  1530.     if(obj->lamplit) {
  1531.         if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
  1532.                 obj->otyp == BRASS_LANTERN) {
  1533.             Your("lamp is now off.");
  1534.             obj->lamplit = 0;
  1535.             check_lamps();
  1536.             return(TRUE);
  1537.         } 
  1538.  
  1539.         if(snuff_candle(obj)) return(TRUE);
  1540.     }
  1541.  
  1542.     return(FALSE);
  1543. }
  1544.  
  1545. static void
  1546. use_lamp(obj)
  1547. struct obj *obj;
  1548. {
  1549.     if(Underwater) {
  1550.         pline("This is not a diving lamp.");
  1551.         return;
  1552.     }
  1553.     if(obj->lamplit) {
  1554.         if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
  1555.                 obj->otyp == BRASS_LANTERN)
  1556.             Your("lamp is now off.");
  1557.         else
  1558.             You("snuff out %s.", the(xname(obj)));
  1559.         obj->lamplit = 0;
  1560.         check_lamps();
  1561.         return;
  1562.     }
  1563.     if (!Is_candle(obj) && obj->spe <= 0) {
  1564.         if (obj->otyp == BRASS_LANTERN)
  1565.             Your("lamp has run out of power.");
  1566.         else pline("This %s has no oil.", xname(obj));
  1567.         return;
  1568.     }
  1569.     if(obj->cursed && !rn2(2))
  1570.         pline("%s flicker%s on for a moment, then die%s.", 
  1571.                The(xname(obj)),
  1572.                obj->quan > 1L ? "" : "s",
  1573.                obj->quan > 1L ? "" : "s");
  1574.     else {
  1575.         if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
  1576.                 obj->otyp == BRASS_LANTERN)
  1577.             Your("lamp is now on.");
  1578.         else
  1579.             pline("%s%s flame%s burn%s%s", The(xname(obj)),
  1580.                 obj->quan > 1L ? "'" : "'s",
  1581.                 obj->quan > 1L ? "s" : "",
  1582.                 obj->quan > 1L ? "" : "s",
  1583.             Blind ? "." : " brightly!");
  1584.         obj->lamplit = 1;
  1585.         check_lamps();
  1586.         if (obj->unpaid && Is_candle(obj) &&
  1587.             obj->age == 20L * (long)objects[obj->otyp].oc_cost) {
  1588.             const char *it_them = obj->quan > 1L ? "them" : "it";
  1589.             You("use %s, you've bought %s!", it_them, it_them);
  1590.             bill_dummy_object(obj);
  1591.         }
  1592.     }
  1593. }
  1594.  
  1595. void
  1596. check_lamps()
  1597. {
  1598.     register struct obj *obj;
  1599.     int lamps = 0;
  1600.  
  1601.     for(obj = invent; obj; obj = obj->nobj)
  1602.         if (obj->lamplit) {
  1603.             lamps++;
  1604.             break;
  1605.         }
  1606.  
  1607.     if (lamps && u.nv_range == 1) {
  1608.         u.nv_range = 3;
  1609.         vision_full_recalc = 1;
  1610.     } else if (!lamps && u.nv_range == 3) {
  1611.         u.nv_range = 1;
  1612.         vision_full_recalc = 1;
  1613.     }
  1614. }
  1615.  
  1616. static const char NEARDATA cuddly[] = { TOOL_CLASS, 0 };
  1617.  
  1618. int
  1619. dorub()
  1620. {
  1621.     struct obj *obj = getobj(cuddly, "rub");
  1622.  
  1623.     if(!obj || (obj != uwep && !wield_tool(obj))) return 0;
  1624.  
  1625.     /* now uwep is obj */
  1626.     if (uwep->otyp == MAGIC_LAMP) {
  1627.         if (uwep->spe > 0 && !rn2(3)) {
  1628.         djinni_from_bottle(uwep);
  1629.         makeknown(MAGIC_LAMP);
  1630.         uwep->otyp = OIL_LAMP;
  1631.         uwep->spe = 1; /* for safety */
  1632.         uwep->age = rn1(500,1000);
  1633.         } else if (rn2(2) && !Blind)
  1634.         You("see a puff of smoke.");
  1635.         else pline(nothing_happens);
  1636.     } else if (obj->otyp == BRASS_LANTERN) {
  1637.         /* message from Adventure */
  1638.         pline("Rubbing the electric lamp is not particularly rewarding.");
  1639.         pline("Anyway, nothing exciting happens.");
  1640.     } else pline(nothing_happens);
  1641.     return 1;
  1642. }
  1643.  
  1644. int
  1645. dojump()
  1646. {
  1647.     coord cc;
  1648.     register struct monst *mtmp;
  1649.     if (!Jumping || Levitation) {
  1650.         You("can't jump very far.");
  1651.         return 0;
  1652.     } else if (u.uswallow) {
  1653.         pline("You've got to be kidding!");
  1654.         return 0;
  1655.     } else if (u.uinwater) {
  1656.         pline("This calls for swimming, not jumping!");
  1657.         return 0;
  1658.     } else if (u.ustuck) {
  1659.         You("cannot escape from %s!", mon_nam(u.ustuck));
  1660.         return 0;
  1661.     } else if (near_capacity() > UNENCUMBERED) {
  1662.         You("are carrying too much to jump!");
  1663.         return 0;
  1664.     } else if (u.uhunger <= 100 || ACURR(A_STR) < 6) {
  1665.         You("lack the strength to jump!");
  1666.         return 0;
  1667.     }
  1668.     pline("Where do you want to jump?");
  1669.     cc.x = u.ux;
  1670.     cc.y = u.uy;
  1671.     getpos(&cc, TRUE, "the desired position");
  1672.         if(cc.x == -10) return 0; /* user pressed esc */
  1673.     if (!(Jumping & ~INTRINSIC) && distu(cc.x, cc.y) != 5) {
  1674.         pline("Illegal move!");
  1675.         return 0;
  1676.     } else if (distu(cc.x, cc.y) > 9) {
  1677.         pline("Too far!");
  1678.         return 0;
  1679.     } else if (!cansee(cc.x, cc.y)) {
  1680.         You("cannot see where to land!");
  1681.         return 0;
  1682.     } else if (mtmp = m_at(cc.x, cc.y)) {
  1683.         You("cannot trample %s!", mon_nam(mtmp));
  1684.         return 0;
  1685.     } else if (!isok(cc.x, cc.y) ||
  1686. #ifdef POLYSELF
  1687.         (IS_ROCK(levl[cc.x][cc.y].typ) && !passes_walls(uasmon)) ||
  1688. #else
  1689.         IS_ROCK(levl[cc.x][cc.y].typ) ||
  1690. #endif
  1691.         sobj_at(BOULDER, cc.x, cc.x) ) {
  1692.             You("cannot jump there!");
  1693.             return 0;
  1694.     } else {
  1695.         if(u.utrap)
  1696.         switch(u.utraptype) {
  1697.         case TT_BEARTRAP: {
  1698.             register long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
  1699.             You("rip yourself out of the bear trap!  Ouch!");
  1700.             losehp(rnd(10), "jumping out of a bear trap", KILLED_BY);
  1701.             set_wounded_legs(side, rn1(1000,500));
  1702.             break;
  1703.           }
  1704.         case TT_PIT:
  1705.             You("leap from the pit!");
  1706.             break;
  1707.         case TT_WEB:
  1708.             You("tear the web apart as you pull yourself free!");
  1709.             deltrap(t_at(u.ux,u.uy));
  1710.             break;
  1711.         case TT_LAVA:
  1712.             You("pull yourself above the lava!");
  1713.             u.utrap = 0;
  1714.             return 1;
  1715.         case TT_INFLOOR:
  1716.             You("strain your %s, but are still stuck in the floor.",
  1717.             makeplural(body_part(LEG)));
  1718.             set_wounded_legs(LEFT_SIDE, rn1(10, 11));
  1719.             set_wounded_legs(RIGHT_SIDE, rn1(10, 11));
  1720.             return 1;
  1721.         }
  1722.  
  1723.         teleds(cc.x, cc.y);
  1724.         nomul(-1);
  1725.         nomovemsg = "";
  1726.         morehungry(rnd(25));
  1727.         return 1;
  1728.     }
  1729. }
  1730.  
  1731. static void
  1732. use_tinning_kit(obj)
  1733. register struct obj *obj;
  1734. {
  1735.     register struct obj *corpse, *can;
  1736.  
  1737.     /* This takes only 1 move.  If this is to be changed to take many
  1738.      * moves, we've got to deal with decaying corpses...
  1739.      */
  1740.     if (!(corpse = floorfood("can", 1))) return;
  1741.     if (corpse->oeaten) {
  1742.         You("cannot tin something which is partly eaten.");
  1743.         return;
  1744.     }
  1745.     if ((corpse->corpsenm == PM_COCKATRICE)
  1746. #ifdef POLYSELF
  1747.         && !resists_ston(uasmon)
  1748. #endif
  1749.         && !uarmg) {
  1750. pline("Tinning a cockatrice corpse without gloves was not a very wise move...");
  1751. #if defined(POLYSELF)
  1752. /* this will have to change if more monsters can poly */
  1753.         if(!(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)))
  1754. #endif
  1755.         {
  1756.         You("turn to stone...");
  1757.         killer_format = KILLED_BY;
  1758.         killer = "trying to tin a cockatrice without gloves";
  1759.         done(STONING);
  1760.         }
  1761.     }
  1762.     if (mons[corpse->corpsenm].cnutrit == 0) {
  1763.         You("can't tin something that insubstantial!");
  1764.         return;
  1765.     }
  1766.     if (is_rider(&mons[corpse->corpsenm])) {
  1767.         revive_corpse(corpse, 0, FALSE);
  1768.         verbalize("Yes....  But War does not preserve its enemies...");
  1769.         return;
  1770.     }
  1771.     if(can = mksobj(TIN, FALSE, FALSE)) {
  1772.         can->corpsenm = corpse->corpsenm;
  1773.         can->cursed = obj->cursed;
  1774.         can->blessed = obj->blessed;
  1775.         can->owt = weight(can);
  1776.         can->known = 1;
  1777.         can->spe = -1;  /* Mark tinned tins. No spinach allowed... */
  1778.         can = hold_another_object(can, "You make, but cannot pick up, %s.",
  1779.                       doname(can), (const char *)0);
  1780.         if (carried(corpse)) useup(corpse);
  1781.         else useupf(corpse);
  1782.     } else impossible("Tinning failed.");
  1783. }
  1784.  
  1785. void
  1786. use_unicorn_horn(obj)
  1787. struct obj *obj;
  1788. {
  1789.     boolean blessed = (obj && obj->blessed);
  1790.     boolean did_something = FALSE;
  1791.  
  1792.     if (obj && obj->cursed) {
  1793.         switch (rn2(6)) {
  1794.             static char buf[BUFSZ];
  1795.             case 0: make_sick(Sick ? 1L : (long) rn1(20, 20), TRUE);
  1796.                 Strcpy(buf, xname(obj));
  1797.                 u.usick_cause = (const char *)buf;
  1798.                 break;
  1799.             case 1: make_blinded(Blinded + (long) rnd(100), TRUE);
  1800.                 break;
  1801.             case 2: if (!Confusion)
  1802.                 You("suddenly feel %s.",
  1803.                     Hallucination ? "trippy" : "confused");
  1804.                 make_confused(HConfusion + (long) rnd(100), TRUE);
  1805.                 break;
  1806.             case 3: make_stunned(HStun + (long) rnd(100), TRUE);
  1807.                 break;
  1808.             case 4: (void) adjattrib(rn2(6), -1, FALSE);
  1809.                 break;
  1810.             case 5: make_hallucinated(HHallucination + (long) rnd(100),
  1811.                 TRUE, 0L);
  1812.                 break;
  1813.         }
  1814.         return;
  1815.     }
  1816.         
  1817.     if (Sick) {
  1818.         make_sick(0L, TRUE);
  1819.         did_something++;
  1820.     }
  1821.     if (Blinded > (long)(u.ucreamed+1) && (!did_something || blessed)) {
  1822.         make_blinded(u.ucreamed ? (long)(u.ucreamed+1) : 0L, TRUE);
  1823.         did_something++;
  1824.     }
  1825.     if (Hallucination && (!did_something || blessed)) {
  1826.         make_hallucinated(0L, TRUE, 0L);
  1827.         did_something++;
  1828.     }
  1829.     if (Vomiting && (!did_something || blessed)) {
  1830.         make_vomiting(0L, TRUE);
  1831.         did_something++;
  1832.     }
  1833.     if (HConfusion && (!did_something || blessed)) {
  1834.         make_confused(0L, TRUE);
  1835.         did_something++;
  1836.     }
  1837.     if (HStun && (!did_something || blessed)) {
  1838.         make_stunned(0L, TRUE);
  1839.         did_something++;
  1840.     }
  1841.     if (!did_something || blessed) {
  1842.         register int j;
  1843.         int did_stat = 0;
  1844.         int i = rn2(A_MAX);
  1845.         for(j=0; j<A_MAX; j++) {
  1846.             /* don't recover strength lost while hungry */
  1847.             if ((blessed || j==i) &&
  1848.                 ((j != A_STR || u.uhs < WEAK)
  1849.                 ? (ABASE(i) < AMAX(i))
  1850.                 : (ABASE(A_STR) < (AMAX(A_STR) - 1)))) {
  1851.                 did_something++;
  1852.                 /* They may have to use it several times... */
  1853.                 if (!did_stat) {
  1854.                     did_stat++;
  1855.                     pline("This makes you feel good!");
  1856.                 }
  1857.                 ABASE(i)++;
  1858.                 flags.botl = 1;
  1859.             }
  1860.         }
  1861.     }
  1862.     if (!did_something) pline(nothing_happens);
  1863. }
  1864.  
  1865. static void
  1866. use_figurine(obj)
  1867. register struct obj *obj;
  1868. {
  1869.     xchar x, y;
  1870.  
  1871.     if(!getdir(NULL)) {
  1872.         flags.move = multi = 0;
  1873.         return;
  1874.     }
  1875.     x = u.ux + u.dx; y = u.uy + u.dy;
  1876.     if (!isok(x,y)) {
  1877.         You("can't seem to put the figurine there.");
  1878.         return;
  1879.     }
  1880.     if (IS_ROCK(levl[x][y].typ) && !passes_walls(&mons[obj->corpsenm])) {
  1881.         You("can't place a figurine in solid rock!");
  1882.         return;
  1883.     }
  1884.     if (sobj_at(BOULDER,x,y) && !passes_walls(&mons[obj->corpsenm])
  1885.             && !throws_rocks(&mons[obj->corpsenm])) {
  1886.         You("can't fit the figurine on the boulder.");
  1887.         return;
  1888.     }
  1889.     You("%s and it transforms.",
  1890.         (u.dx||u.dy) ? "set the figurine besides you" :
  1891.         (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) ?
  1892.         "release the figurine" :
  1893.         (u.dz < 0 ?
  1894.         "toss the figurine into the air" :
  1895.         "set the figurine on the ground"));
  1896.     make_familiar(obj, u.ux+u.dx, u.uy+u.dy);
  1897.     useup(obj);
  1898. }
  1899.  
  1900. static void
  1901. use_grease(obj)
  1902. struct obj *obj;
  1903. {
  1904.     struct obj *otmp;
  1905.  
  1906.     if (obj->spe > 0) {
  1907.         char allow_all[2];
  1908.         if (obj->cursed && !rn2(2)) {
  1909.             pline("The %s slips from your fingers!",xname(obj));
  1910.             dropx(obj);
  1911.             obj->spe -= 1;
  1912.             return;
  1913.         }
  1914.         allow_all[0] = ALL_CLASSES; allow_all[1] = '\0';
  1915.         otmp = getobj(allow_all,"grease");
  1916.         if (otmp) {
  1917.             You("cover your %s with a thick layer of grease.",xname(otmp));
  1918.             otmp->greased = 1;
  1919.             obj->spe -= 1;
  1920.         }
  1921.     }
  1922. }
  1923.  
  1924. int
  1925. doapply()
  1926. {
  1927.     register struct obj *obj;
  1928.     register int res = 1;
  1929.  
  1930.     if(check_capacity(NULL)) return (0);
  1931.     obj = getobj(tools, "use or apply");
  1932.     if(!obj) return 0;
  1933.  
  1934.     check_unpaid(obj);
  1935.  
  1936.     switch(obj->otyp){
  1937.     case BLINDFOLD:
  1938.         if (obj == ublindf) {
  1939.             if(cursed(obj)) break;
  1940.             else Blindf_off(obj);
  1941.         } 
  1942.         else if (!ublindf) Blindf_on(obj);
  1943.         else You("are already %s", ublindf->otyp == TOWEL ?
  1944.              "covered by a towel." : "wearing a blindfold!");
  1945.         break;
  1946.     case LARGE_BOX:
  1947.     case CHEST:
  1948.     case ICE_BOX:
  1949.     case SACK:
  1950.     case BAG_OF_HOLDING:
  1951.     case OILSKIN_SACK:
  1952.         res = use_container(obj, 1); 
  1953.         break;
  1954.     case BAG_OF_TRICKS:
  1955.         if(obj->spe > 0) {
  1956.             register int cnt = 1;
  1957.  
  1958.             obj->spe -= 1;
  1959.             if(!rn2(23)) cnt += rn2(7) + 1;
  1960.             while(cnt--)
  1961.                 (void) makemon((struct permonst *) 0, u.ux, u.uy);
  1962.             makeknown(BAG_OF_TRICKS);
  1963.         } else
  1964.             pline(nothing_happens);
  1965.         break;
  1966.     case CAN_OF_GREASE:
  1967.         use_grease(obj);
  1968.         break;
  1969.     case LOCK_PICK:
  1970. #ifdef TOURIST
  1971.     case CREDIT_CARD:
  1972. #endif
  1973.     case SKELETON_KEY:
  1974.         (void) pick_lock(obj);
  1975.         break;
  1976.     case PICK_AXE:
  1977.         res = use_pick_axe(obj);
  1978.         break;
  1979.     case TINNING_KIT:
  1980.         use_tinning_kit(obj);
  1981.         break;
  1982. #ifdef WALKIES
  1983.     case LEASH:
  1984.         use_leash(obj);
  1985.         break;
  1986. #endif
  1987.     case MAGIC_WHISTLE:
  1988.         use_magic_whistle(obj);
  1989.         break;
  1990.     case TIN_WHISTLE:
  1991.         use_whistle(obj);
  1992.         break;
  1993.     case STETHOSCOPE:
  1994.         res = 0;
  1995.         use_stethoscope(obj);
  1996.         break;
  1997.     case MIRROR:
  1998.         res = use_mirror(obj);
  1999.         break;
  2000.     case BELL:
  2001.     case BELL_OF_OPENING:
  2002.             use_bell(obj);
  2003.         break;
  2004.     case CANDELABRUM_OF_INVOCATION:
  2005.         use_candelabrum(obj);
  2006.         break;
  2007.     case WAX_CANDLE:
  2008.     case TALLOW_CANDLE:
  2009.         use_candle(obj);
  2010.         break;
  2011.     case OIL_LAMP:
  2012.     case MAGIC_LAMP:
  2013.     case BRASS_LANTERN:
  2014.         use_lamp(obj);
  2015.         break;
  2016. #ifdef TOURIST
  2017.     case EXPENSIVE_CAMERA:
  2018.         res = use_camera(obj); 
  2019.         break;
  2020. #endif
  2021.     case TOWEL:
  2022.         res = use_towel(obj); 
  2023.         break;
  2024.     case CRYSTAL_BALL:
  2025.         use_crystal_ball(obj);
  2026.         break;
  2027.     case MAGIC_MARKER:
  2028.         res = dowrite(obj);
  2029.         break;
  2030.     case TIN_OPENER:
  2031.         if(!carrying(TIN)) {
  2032.             You("have no tin to open.");
  2033.             goto xit;
  2034.         }
  2035.         You("cannot open a tin without eating or discarding its contents.");
  2036.         if(flags.verbose)
  2037.             pline("In order to eat, use the 'e' command.");
  2038.         if(obj != uwep)
  2039.     pline("Opening the tin will be much easier if you wield the tin opener.");
  2040.         goto xit;
  2041.  
  2042.     case FIGURINE:
  2043.         use_figurine(obj);
  2044.         break;
  2045.     case UNICORN_HORN:
  2046.         use_unicorn_horn(obj);
  2047.         break;
  2048.     case WOODEN_FLUTE:
  2049.     case MAGIC_FLUTE:
  2050.     case TOOLED_HORN:
  2051.     case FROST_HORN:
  2052.     case FIRE_HORN:
  2053.     case WOODEN_HARP:
  2054.     case MAGIC_HARP:
  2055.     case BUGLE:
  2056.     case LEATHER_DRUM:
  2057.     case DRUM_OF_EARTHQUAKE:
  2058.         res = do_play_instrument(obj);
  2059.         break;
  2060.     case HORN_OF_PLENTY:
  2061.         if (obj->spe > 0) {
  2062.             struct obj *otmp;
  2063.             const char *what;
  2064.  
  2065. #ifdef MAC
  2066.             char melody [ 3 ] = { 0 , 0 , 0 } ;
  2067.             melody [ 0 ] = rn2 ( 8 ) + 'A' ;
  2068.             melody [ 1 ] = rn2 ( 8 ) + 'A' ;
  2069.             mac_speaker ( obj , & melody ) ;
  2070. #endif
  2071.  
  2072.             obj->spe -= 1;
  2073.             if (!rn2(13)) {
  2074.             otmp = mkobj(POTION_CLASS, FALSE);
  2075.             if (objects[otmp->otyp].oc_magic) do {
  2076.                 otmp->otyp = rnd_class(POT_BOOZE, POT_WATER);
  2077.             } while (otmp->otyp == POT_SICKNESS);
  2078.             what = "A potion";
  2079.             } else {
  2080.             otmp = mkobj(FOOD_CLASS, FALSE);
  2081.             if (otmp->otyp == FOOD_RATION && !rn2(7))
  2082.                 otmp->otyp = LUMP_OF_ROYAL_JELLY;
  2083.             what = "Some food";
  2084.             }
  2085.             pline("%s spills out.", what);
  2086.             otmp->blessed = obj->blessed;
  2087.             otmp->cursed = obj->cursed;
  2088.             otmp->owt = weight(otmp);
  2089.             otmp = hold_another_object(otmp, u.uswallow ?
  2090.                            "Oops!  %s away from you!" :
  2091.                            "Oops!  %s to the floor!",
  2092.                            The(aobjnam(otmp, "slip")),
  2093.                            (const char *)0);
  2094.             makeknown(HORN_OF_PLENTY);
  2095.         } else
  2096.             pline(nothing_happens);
  2097.         break;
  2098.     default:
  2099.         pline("Sorry, I don't know how to use that.");
  2100.     xit:
  2101.         nomul(0);
  2102.         return 0;
  2103.     }
  2104.     nomul(0);
  2105.     return res;
  2106. }
  2107.  
  2108. #endif /* OVLB */
  2109.  
  2110. /*apply.c*/
  2111.